#ifndef BASE_H
#define BASE_H
#include "helpfunc.h"
class sendMapV {
public:
    vector<char> data ;
    bool got = false;
    int sendTime = 0;
};
class base
{
public:
    int dataSock, numSock;
    int oneLen;
    int numPort, dataPort;
    mybuf wrietBuf, wrietBuf2;
    vector<char> key = helpFunc::con_key;
    uint64_t sendPos = 0, peerPos = 0, recvPos = 0;
    int packSendTime = helpFunc::con_packEffectTime;
    uint64_t   lastPackCreateTime = helpFunc::getTime();
    map<uint64_t, sendMapV> sendMap;
    int rNet = 0, wNet = 0, maxGotLen = 0, maxSenLen = 0;
    int timeoutInter = helpFunc::con_timeoutInternal;
    float gotRate = 1;
    int maxAskTime = calAskTime();
    int dataS, numS;
    uint64_t lastRecvTime = helpFunc::getTime();

    base(int oneLen_a) {
        sendMap[0]=sendMapV();
        oneLen = oneLen_a;
        iniSock();
    }

    int calAskTime() {
        if (gotRate > 0.9)
            return 2;
        if (gotRate > 0.75)
            return 3;
        if (gotRate > 0.5)
            return 4;
        if (gotRate > 0.25)
            return 5;
        if (gotRate > 0.1)
            return 8;
        return 20;
    }
    void reFreshSendMap() {
        if (sendMap[sendPos].data.size() == 0)
            return;
        if (helpFunc::getTime() > lastPackCreateTime + packSendTime) {
            sendPos++;
            sendMap[sendPos]=sendMapV();
            lastPackCreateTime = helpFunc::getTime();
        }
    }

    void tellAddBuf(int l) {
        wrietBuf2.writeDWord(l);
    }
    uint64_t calWaitTime()
    {
        if (sendMap.at(sendPos).data.size() == 0)
            return timeoutInter;
        uint64_t t = lastPackCreateTime + packSendTime - helpFunc::getTime();
        if (t > timeoutInter)
            return timeoutInter;
        if (t <= 0)
            return 1;
        return t;
    }

    void dealDataRecv()  {
        auto r = helpFunc::tcpRead(dataSock);
        rNet += r.size();
        if (r.size() + sendMap.at(sendPos).data.size() >= oneLen)
            lastPackCreateTime = helpFunc::getTime();
        int pos = 0;
        while (true) {
            int ll = oneLen - sendMap.at(sendPos).data.size();
            if (r.size() >= pos + ll) {
                vector<char> temp=sendMap.at(sendPos).data;
                temp.insert(temp.end(),r.begin()+pos,r.begin()+pos+ll);
                pos += ll;
                sendMap.at(sendPos).data = temp;
                sendPos++;
                sendMap[sendPos]= sendMapV();
            } else {
                auto temp = sendMap.at(sendPos).data;
                temp.insert(temp.end(),r.begin()+pos,r.end());
                sendMap.at(sendPos).data = temp;
                break;
            }
        }
    }

    void iniSock(){
        dataS = socket (AF_INET, SOCK_STREAM, 0);
        dataPort = helpFunc::bindAnyPort(dataS,helpFunc::ip_str2int("127.0.0.1"),7777);
        numS = socket (AF_INET, SOCK_STREAM, 0);
        numPort = helpFunc::bindAnyPort(numS,helpFunc::ip_str2int("127.0.0.1"),7778);
        listen(dataS,1);
        listen(numS,1);
        cout<<"ports:"<<dataPort<<" "<<numPort<<endl;
    }
    void doAccept() {
        dataSock=    helpFunc::tcpAccept(dataS);
        helpFunc::setNonblock(dataSock);
        close(dataS);
        numSock=    helpFunc::tcpAccept(numS);
        helpFunc::setNonblock(numSock);
        close(numS);
        cout<<"inter conn ok"<<endl;
    }
};

#endif // BASE_H
